let _Vue = null;

export default class VueRouter{
  static install(Vue){
    if(VueRouter.install.installed){
      return
    }
    VueRouter.install.installed = true;

    _Vue = Vue;
   
    _Vue.mixin({
      beforeCreate(){
        if( this.$options.router){
          _Vue.prototype.$router = this.$options.router
          this.$options.router.init();
        }
      }
    })
  }

  constructor(options){
    this.options = options;
    this.routeMap = {};
    this.data = _Vue.observable({
      current: '/'
    })
  }

  init(){
    this.createRouteMap();
    this.initComponents(_Vue);
    this.initEvent();
  }

  createRouteMap(){
    this.options.routes.forEach(route=>{
      this.routeMap[route.path] = route.component;
    })
  }

  initComponents(Vue){
    const self = this;

    Vue.component('router-link', {
      props: {
        to: String,
      },
      render(h){
        return h('a', { 
          attrs: {
            href:  this.to,
          },
          on:{
            click: this.clcikHandler
          }
        },[this.$slots.default])
      },
      methods:{
        clcikHandler(e){
          e.preventDefault();

          if(self.options.mode !=='hash'){
            history.pushState({}, '',  this.to);
          }else{
            window.location.hash = this.to;
          }
          this.$router.data.current = this.to;
        }
      }
    })
    
    Vue.component('router-view', {
      props: {
        to: String,
      },
      render(h){
        const component=  self.routeMap[self.data.current];
        return h(component)
      }
    })
  }

  initEvent(){
    if(this.options.mode ==='hash'){
      window.location.hash ='/'
    }
    window.addEventListener('hashchang', ()=>{
      this.data.current = window.location.hash.slice(1);
    })
    window.addEventListener('popstate', ()=>{
      this.data.current = window.location.pathname;
    })

  
  }
}